package processingdata.ufo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import Control.Airport;
import Control.MilitaryBase;
import Control.PopDensity;
import Control.UFO;
import Control.WeatherStation;

public class DistanceComputer {

	static ArrayList<ArrayList<ArrayList<ArrayList<UFO>>>> wholeUfos = new ArrayList<ArrayList<ArrayList<ArrayList<UFO>>>>();
	static ArrayList<Airport> airports = new ArrayList<Airport>();
	static ArrayList<MilitaryBase> bases = new ArrayList<MilitaryBase>();

	static ArrayList<PopDensity> densities = new ArrayList<PopDensity>();

	static ArrayList<WeatherStation> stations=new ArrayList<WeatherStation>();
	public static void main(String args[]) throws Exception {
		loadUfosData();
		loadAirportData();
		loadMilitaryData();
		loadDensityData();
		loadWeatherStationData();
		computeClosestAirport();
		computeClosestBase();
		computeClosestDensity();
		computeClosestWeatherStation();
		serializeUfoData();
	}
	
	public static void loadWeatherStationData() throws Exception, IOException
	{
		ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("data/stations.ser")));
		stations=(ArrayList<WeatherStation>) ois.readObject();
		
	}

	public static void loadDensityData() throws Exception, IOException {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				new File("data/density.ser")));
		densities = (ArrayList<PopDensity>) ois.readObject();
	}

	static void serializeUfoData() throws FileNotFoundException, IOException {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
				new File("data/finalUfos.ser")));
		oos.writeObject(wholeUfos);
		oos.close();
	}

	static void computeClosestDensity() {
		for (int s = 0; s < wholeUfos.size(); s++) {
			for (int m = 0; m < wholeUfos.get(s).size(); m++) {
				for (int h = 0; h < wholeUfos.get(s).get(m).size(); h++) {
					for (int u = 0; u < wholeUfos.get(s).get(m).get(h).size(); u++) {
						UFO ufo = wholeUfos.get(s).get(m).get(h).get(u);
						float x1 = ufo.getCoordinates().x;
						float y1 = ufo.getCoordinates().y;
						
						double minDistance = Float.MAX_VALUE;
						double populationDensity=Float.MAX_VALUE;
						String minDensityId = densities.get(0).getDensityId();
						for (int d = 0; d < densities.size(); d++) {
							PopDensity popDensity = densities.get(d);
							float x2 = popDensity.getCoordinates().x;
							float y2 = popDensity.getCoordinates().y;
							double distance = computeDistance(x1, y1, x2, y2);
							if (distance < minDistance) {
								minDistance = distance;
								minDensityId = popDensity.getDensityId();
								populationDensity=popDensity.getPopulationDensity();
							}

						}
						
						ufo.setClosestDensityId(minDensityId);
						ufo.setPopulationDensity(populationDensity);
						
					}
				}
			}
		}
	}

	static void computeClosestAirport() {
		for (int s = 0; s < wholeUfos.size(); s++) {
			for (int m = 0; m < wholeUfos.get(s).size(); m++) {
				for (int h = 0; h < wholeUfos.get(s).get(m).size(); h++) {
					for (int u = 0; u < wholeUfos.get(s).get(m).get(h).size(); u++) {
						UFO ufo = wholeUfos.get(s).get(m).get(h).get(u);
						float x1 = ufo.getCoordinates().x;
						float y1 = ufo.getCoordinates().y;

						double minDistance = Float.MAX_VALUE;
						String minAirportId = airports.get(0).getAirportId();
						for (int a = 0; a < airports.size(); a++) {
							Airport airport = airports.get(a);
							float x2 = airport.getCoordinates().x;
							float y2 = airport.getCoordinates().y;
							double distance = computeDistance(x1, y1, x2, y2);
							if (distance < minDistance) {
								minDistance = distance;
								minAirportId = airport.getAirportId();
							}

						}
						ufo.setClosestAirportId(minAirportId);
						minDistance = minDistance * 111;
						ufo.setDistanceFromClosestAirport(minDistance);
					}
				}
			}
		}
	}
	
	static void computeClosestWeatherStation() {
		for (int s = 0; s < wholeUfos.size(); s++) {
			for (int m = 0; m < wholeUfos.get(s).size(); m++) {
				for (int h = 0; h < wholeUfos.get(s).get(m).size(); h++) {
					for (int u = 0; u < wholeUfos.get(s).get(m).get(h).size(); u++) {
						UFO ufo = wholeUfos.get(s).get(m).get(h).get(u);
						float x1 = ufo.getCoordinates().x;
						float y1 = ufo.getCoordinates().y;

						double minDistance = Float.MAX_VALUE;
						String weatherStationName = stations.get(0).getName();
						for (int ws = 0; ws < stations.size(); ws++) {
							WeatherStation station = stations.get(ws);
							float x2 = station.getCoordinates().x;
							float y2 = station.getCoordinates().y;
							double distance = computeDistance(x1, y1, x2, y2);
							if (distance < minDistance) {
								minDistance = distance;
								weatherStationName = station.getName();
							}

						}
						ufo.setClosestWeatherStationName(weatherStationName);
						minDistance = minDistance * 111;
						ufo.setDistanceFromClosestWeatherStation(minDistance);
					}
				}
			}
		}
	}

	static void computeClosestBase() {

		for (int s = 0; s < wholeUfos.size(); s++) {
			for (int m = 0; m < wholeUfos.get(s).size(); m++) {
				for (int h = 0; h < wholeUfos.get(s).get(m).size(); h++) {
					for (int u = 0; u < wholeUfos.get(s).get(m).get(h).size(); u++) {
						UFO ufo = wholeUfos.get(s).get(m).get(h).get(u);
						float x1 = ufo.getCoordinates().x;
						float y1 = ufo.getCoordinates().y;

						double minDistance = Float.MAX_VALUE;
						String minBaseName = bases.get(0).getName();
						for (int b = 0; b < bases.size(); b++) {
							MilitaryBase base = bases.get(b);
							float x2 = base.getCoordinates().x;
							float y2 = base.getCoordinates().y;
							double distance = computeDistance(x1, y1, x2, y2);
							if (distance < minDistance) {
								minDistance = distance;
								minBaseName = base.getName();
							}

						}
						ufo.setClosestBaseName(minBaseName);
						System.out.println(minDistance);
						minDistance = minDistance * 111;
						ufo.setDistanceFromClosestMilitaryBase(minDistance);
					}
				}
			}
		}

	}

	static double computeDistance(float x1, float y1, float x2, float y2) {
		double distance;
		float formula = ((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1));
		distance = Math.sqrt(formula);
		return distance;
	}

	static void loadUfosData() throws FileNotFoundException, IOException,
			ClassNotFoundException {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				new File("data/newufos.ser")));
		wholeUfos = (ArrayList<ArrayList<ArrayList<ArrayList<UFO>>>>) ois
				.readObject();
	}

	static void loadAirportData() throws IOException, ClassNotFoundException {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				new File("data/airports.ser")));
		airports = (ArrayList<Airport>) ois.readObject();

	}

	static void loadMilitaryData() throws FileNotFoundException, IOException,
			ClassNotFoundException {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				new File("data/military.ser")));
		bases = (ArrayList<MilitaryBase>) ois.readObject();

	}

}
